package com.thundersoft.camera20;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NavUtils;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaRecorder;

import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;

import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {


    private static final String TAG = "Camera2";

    private static final String TAG_PREVIEW = "预览";

    private static final SparseIntArray ORIENTATION = new SparseIntArray();


    static {
        ORIENTATION.append(Surface.ROTATION_0, 90);
        ORIENTATION.append(Surface.ROTATION_90, 0);
        ORIENTATION.append(Surface.ROTATION_180, 270);
        ORIENTATION.append(Surface.ROTATION_270, 180);
    }

    private String mCameraId;
    private static Activity mActivity;
    private HandlerThread mBackgroundThread;
    private Handler mBackgroundHandler;
    private String mFolderPath = "/abc/";//保存视频，图片的路径
    private Size mPreviewSize;
    private ImageReader mImageReader;
    private CameraDevice mCameraDevice;
    private CameraCaptureSession mCameraCaptureSession;
    private CameraCaptureSession mPreviewSession;
    private CaptureRequest mPreviewRequest;
    private CaptureRequest.Builder mPreviewRequestBuilder;
    private CaptureRequest.Builder mPreviewBuilder;
    private AutoFitTextureView textureView;
    private Surface mPreviewSurface;


    private Integer mSensorOrientation;

    private boolean mIsRecordingVideo;//开始停止录像

    private MediaRecorder mMediaRecorder;
    private String mNextVideoAbsolutePath;

    // private Semaphore mCameraOpenCloseLock = new Semaphore(1,true);
    private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90;
    private static final int SENSOR_ORIENTATION_INVERSE_DEGREES = 270;

    private static final int PERMISSION_REQ_ID = 22;
    private Size[] mSize=null;

    List<String> mPermissionList = new ArrayList<>();

    private static final String[] REQUESTED_PERMISSION = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO};

    TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
            setupCamera(width, height);
            configureTransform(width, height);
            openCamera();
            // getMatchingSize();
        }


        @Override
        public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int width, int height) {

            configureTransform(width, height);
        }

        @Override
        public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {

        }


    };


    private void setupCamera(int width, int height) {
        //获取摄像头的管理者CameraManager
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

        try {
            //遍历所有摄像头
            for (String cameraId : manager.getCameraIdList()) {
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
                //默认打开后置摄像头，忽视前置摄像头
                if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT)
                    continue;
                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);

                int orientation = getResources().getConfiguration().orientation;
                mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
                if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    textureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
                } else {
                    textureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
                }
                mCameraId = cameraId;
                break;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        List list1 = new ArrayList();
        List list2 = new ArrayList();
        List list3 = new ArrayList();
        try {
            CameraManager mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
            for (final String cameraId : mCameraManager.getCameraIdList()) {
                CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId);
                StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                Size[] sizes = streamConfigurationMap.getOutputSizes(ImageFormat.JPEG);
                DisplayMetrics displayMetrics = getResources().getDisplayMetrics();//获取屏幕分辨率
                int deviceWidth = displayMetrics.widthPixels;
                int deviceHeight = displayMetrics.heightPixels;
                Log.d(TAG, "getMatchingSize: 屏幕密度宽度=" + deviceWidth);
                Log.d(TAG, "getMatchingSize: 屏幕密度长度=" + deviceHeight);

                Double width;
                Double height;
                /*for (int i = 0; i < sizes.length; i++) {
                    Size itemSize = sizes[i];
                    Log.d(TAG, "onOptionsItemSelected: "+Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight()));
                    if ((Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight())) == 1.0) {
                        //1:1
                        Log.d(TAG, "onOptionsItemSelected1:1: " + itemSize.getWidth() + " " + itemSize.getHeight());
                       *//* list1.add(itemSize.getWidth());
                        list1.add(itemSize.getHeight());*//*
                    }else if ((Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight())) == (Double.valueOf(4)/Double.valueOf(3))){
                        Log.d(TAG, "onOptionsItemSelected4:3: " + itemSize.getWidth() + " " + itemSize.getHeight());
                    }else if ((Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight())) == (Double.valueOf(16)/Double.valueOf(9))){
                        Log.d(TAG, "onOptionsItemSelected16:9: " + itemSize.getWidth() + " " + itemSize.getHeight());
                    }

                }*/
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        switch (item.getItemId()) {
            case R.id.ic_one_to_one:
                for (int i = 0; i < sizes.length; i++) {
                    Size itemSize = sizes[i];
                    Log.d(TAG, "onOptionsItemSelected: "+Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight()));
                    if ((Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight())) == 1.0) {
                        //1:1
                        Log.d(TAG, "onOptionsItemSelected1:1: " + itemSize.getWidth() + " " + itemSize.getHeight());
                       /* list1.add(itemSize.getWidth());
                        list1.add(itemSize.getHeight());*/
                    }else if ((Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight())) == (Double.valueOf(4)/Double.valueOf(3))){
                        Log.d(TAG, "onOptionsItemSelected4:3: " + itemSize.getWidth() + " " + itemSize.getHeight());
                    }else if ((Double.valueOf(itemSize.getWidth())/Double.valueOf(itemSize.getHeight())) == (Double.valueOf(16)/Double.valueOf(9))){
                        Log.d(TAG, "onOptionsItemSelected16:9: " + itemSize.getWidth() + " " + itemSize.getHeight());
                    }

                }

                Log.d(TAG, "onOptionsItemSelected1:1: " + Integer.parseInt(list1.get(0).toString()) + " " + Integer.parseInt(list1.get(1).toString()));
                mPreviewSize = new Size(Integer.parseInt(list1.get(0).toString()), Integer.parseInt(list1.get(1).toString()));
                configureTransform(Integer.parseInt(list1.get(0).toString()), Integer.parseInt(list1.get(1).toString()));
                startPreview();
                list1.clear();
                break;
            case R.id.ic_four_to_three:

                Log.d(TAG, "onOptionsItemSelected:4:3 " + Integer.parseInt(list1.get(0).toString()) + " " + Integer.parseInt(list1.get(1).toString()));
                mPreviewSize = new Size(Integer.parseInt(list1.get(0).toString()), Integer.parseInt(list1.get(1).toString()));
                configureTransform(Integer.parseInt(list1.get(0).toString()), Integer.parseInt(list1.get(1).toString()));
                startPreview();
                list1.clear();
                Log.d(TAG, "onOptionsItemSelected1111: "+list1);
                break;
            case R.id.ic_sixteen_to_nine:


                Log.d(TAG, "onOptionsItemSelected:16:9 " + Integer.parseInt(list1.get(2).toString()) + " " + Integer.parseInt(list1.get(3).toString()));
                mPreviewSize = new Size(Integer.parseInt(list1.get(2).toString()), Integer.parseInt(list1.get(3).toString()));
                configureTransform(Integer.parseInt(list1.get(2).toString()), Integer.parseInt(list1.get(3).toString()));
                startPreview();
                list1.clear();
                Log.d(TAG, "onOptionsItemSelecteddddddd: "+list1);
                break;
            default:
        }

        return true;
    }


    private Size getOptimalSize(Size[] sizeMap, int width, int height) {
        List<Size> sizeList = new ArrayList<>();
        for (Size option : sizeMap) {
            if (width > height) {
                if (option.getWidth() > width && option.getHeight() > height) {
                    sizeList.add(option);
                }
            } else {
                if (option.getWidth() > height && option.getHeight() > width) {
                    sizeList.add(option);
                }
            }
        }
        if (sizeList.size() > 0) {
            return Collections.min(sizeList, new Comparator<Size>() {
                @Override
                public int compare(Size size, Size t1) {
                    return Long.signum(size.getWidth() * size.getHeight() - t1.getWidth() * t1.getHeight());

                }
            });
        }
        return sizeMap[0];
    }

    private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            //mCameraOpenCloseLock.release();
            mCameraDevice = cameraDevice;
            startPreview();
            Toast.makeText(MainActivity.this, "照相调用完成000", Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {
            if (mCameraDevice != null) {
                //   mCameraOpenCloseLock.release();
                cameraDevice.close();
                mCameraDevice = null;
                Toast.makeText(MainActivity.this, "照相调用完成sss", Toast.LENGTH_SHORT).show();
                Log.i(TAG, "CameraDeviced DisConnected");
            }


        }

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int i) {
            if (mCameraDevice != null) {
                //  mCameraOpenCloseLock.release();
                cameraDevice.close();
                mCameraDevice = null;
                Activity activity = MainActivity.this;
                if (null != activity) {
                    activity.finish();
                }
                Toast.makeText(MainActivity.this, "摄像头开启失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG, "CameraDevice Error");
            }


        }
    };

    private CameraCaptureSession.CaptureCallback mPreviewCaptureCallback = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {

        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {

        }
    };

    private void startPreview() {
        setupImageReader();
        SurfaceTexture mSurfaceTexture = textureView.getSurfaceTexture();
        //设置TextureView的缓冲区大小
        mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        //获取Surface显示预览数据
        mPreviewSurface = new Surface(mSurfaceTexture);
        try {
            getPreviewRequestBuilder();
            //创建相机捕获会话，第一个参数是捕获数据的输出Surface列表，第二个参数是CameraCaptureSession的状态回调接口，当它创建好后会回调onConfigured方法，第三个参数用来确定Callback
            mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    if (null == mCameraDevice) {
                        return;
                    }
                    mCameraCaptureSession = cameraCaptureSession;
                    repeatPreview();

                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {

                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }


    }

    private void repeatPreview() {

        //设置反复捕获数据的请求，这样预览界面就会一直有数据显示
        try {
            mPreviewRequestBuilder.setTag(TAG_PREVIEW);
            mPreviewRequest = mPreviewRequestBuilder.build();
            Log.d(TAG, "repeatPreview: " + mPreviewRequest + "    " + mBackgroundHandler);
            mCameraCaptureSession.setRepeatingRequest(mPreviewRequest, mPreviewCaptureCallback, mBackgroundHandler);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }


    private void getPreviewRequestBuilder() {
        try {
            mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        //设置预览的显示界面
        mPreviewRequestBuilder.addTarget(mPreviewSurface);
        MeteringRectangle[] meteringRectangles = mPreviewRequestBuilder.get(CaptureRequest.CONTROL_AF_REGIONS);
        if (meteringRectangles != null && meteringRectangles.length > 0) {
            Log.d(TAG, "PreviewRequestBuilder: AF_REGIONS=" + meteringRectangles[0].getRect().toString());

        }
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
    }

    private void setupImageReader() {
        //前三个参数分别是需要的尺寸和格式，最后一个参数代表每次最多获取几帧数据
        mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.JPEG, 1);
        mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader imageReader) {
                Log.i(TAG, "Image Available!");
                Image image = imageReader.acquireLatestImage();

                //开启线程异步保存图片
                new Thread(new ImageSaver(image)).start();

            }
        }, null);

    }


    private void configureTransform(int width, int height) {
        if (textureView == null || mPreviewSize == null) {
            return;
        }
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        Matrix matrix = new Matrix();
        RectF viewRect = new RectF(0, 0, width, height);
        RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
        float centerX = viewRect.centerX();
        float centerY = viewRect.centerY();
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max((float) height / mPreviewSize.getHeight(),
                    (float) width / mPreviewSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
        }
        textureView.setTransform(matrix);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initPermission();
    }


    private void init() {
        textureView = findViewById(R.id.textureView);
        //  Button btn_record_mSensorOrientationvideo = (Button)findViewById(R.id.btn_video_recode);
        textureView.setSurfaceTextureListener(textureListener);

        findViewById(R.id.takePicture).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(MainActivity.this,"照相调用完成",Toast.LENGTH_SHORT);
                capture();
                Toast.makeText(MainActivity.this, "拍照成功", Toast.LENGTH_SHORT).show();
            }
        });

        findViewById(R.id.switch_picture).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                findViewById(R.id.switch_picture).setEnabled(false);

                if (mCameraId.equals(String.valueOf(0))) {
                    Log.d(TAG, "后转前");
                    mCameraId = String.valueOf(1);
                    ORIENTATION.append(Surface.ROTATION_0, 270);
                    ORIENTATION.append(Surface.ROTATION_90, 0);
                    ORIENTATION.append(Surface.ROTATION_180, 90);
                    ORIENTATION.append(Surface.ROTATION_270, 180);
                    closeCamera();
                    reopenCamera();

                } else if (mCameraId.equals(String.valueOf(1))) {
                    Log.d(TAG, "前转后");
                    mCameraId = String.valueOf(0);
                    ORIENTATION.append(Surface.ROTATION_0, 90);
                    ORIENTATION.append(Surface.ROTATION_90, 0);
                    ORIENTATION.append(Surface.ROTATION_180, 270);
                    ORIENTATION.append(Surface.ROTATION_270, 180);
                    closeCamera();
                    reopenCamera();

                }
            }

        });

        findViewById(R.id.btn_video_recode).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                findViewById(R.id.btn_video_recode).setEnabled(false);
                Log.d(TAG, "slf:按钮不可用 ");
                if (mIsRecordingVideo) {
                    mIsRecordingVideo = !mIsRecordingVideo;
                    stopRecordingVideo();
                    //btn_record_video.setText("开始录像");
                    Toast.makeText(MainActivity.this, "录像结束", Toast.LENGTH_SHORT).show();
                } else {
                    // btn_record_video.setText("停止录像");
                    mIsRecordingVideo = !mIsRecordingVideo;
                    startRecordingVideo();

                    Toast.makeText(MainActivity.this, "录像开始", Toast.LENGTH_SHORT).show();
                }

            }
        });

    }

    private void startRecordingVideo() {

        if (mCameraDevice == null || !textureView.isAvailable() || mPreviewSize == null) {

            return;
        }
        try {

            closePreviewSession();

            setUpMediaRecorder();
            //Toast.makeText(MainActivity.this,"1122",Toast.LENGTH_SHORT).show();
            SurfaceTexture texture = textureView.getSurfaceTexture();
            assert texture != null;
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
            mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            List<Surface> surfaces = new ArrayList<>();
            Surface previewSurface = new Surface(texture);
            surfaces.add(previewSurface);
            mPreviewBuilder.addTarget(previewSurface);

            Surface recorderSurface = mMediaRecorder.getSurface();
            surfaces.add(recorderSurface);
            mPreviewBuilder.addTarget(recorderSurface);

            mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    mPreviewSession = cameraCaptureSession;
                    updatePreview();
                    MainActivity.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //开启录像
                            Log.d(TAG, "开始录像");

                            mMediaRecorder.start();

                        }
                    });


                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {

                }
            }, mBackgroundHandler);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.d(TAG, "slf:开始按钮可用 ");
        findViewById(R.id.btn_video_recode).setEnabled(true);
    }

    private void updatePreview() {
        if (mCameraDevice == null) {
            return;
        }
        try {
            mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            HandlerThread thread = new HandlerThread("CameraPreview");
            thread.start();
            mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void setUpMediaRecorder() throws Exception {
        Toast.makeText(MainActivity.this, "录像" + String.valueOf(MediaRecorder.AudioSource.MIC), Toast.LENGTH_SHORT).show();
        Log.d(TAG, "fdjsknfdkjsn" + " " + String.valueOf(MediaRecorder.AudioSource.MIC));
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//用于录制的音源

        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);

        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
            mNextVideoAbsolutePath = getVideoFilePath();
        }
        mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
        mMediaRecorder.setVideoEncodingBitRate(10000000);

        mMediaRecorder.setVideoFrameRate(25);//设置要捕获的视频帧速率
        mMediaRecorder.setVideoSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());//设置要捕获的视频的宽度和高度
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码器，用于录制
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//设置audio的编码格式

        int rotation = MainActivity.this.getWindowManager().getDefaultDisplay().getRotation();
        Log.d(TAG, "setUpMediaRecorder: " + mSensorOrientation);
        switch (mSensorOrientation) {
            case SENSOR_ORIENTATION_DEFAULT_DEGREES:
                mMediaRecorder.setOrientationHint(ORIENTATION.get(rotation));
                break;
            case SENSOR_ORIENTATION_INVERSE_DEGREES:
                mMediaRecorder.setOrientationHint(ORIENTATION.get(rotation));
                break;
        }


        mMediaRecorder.prepare();


    }

    private String getVideoFilePath() {
        setFolderPath(Environment.getExternalStorageDirectory() + getFolderPath());
        return getFolderPath() + System.currentTimeMillis() + ".mp4";
    }

    public void setFolderPath(String path) {
        this.mFolderPath = path;
        File mFolder = new File(path);
        if (!mFolder.exists()) {
            mFolder.mkdirs();
            Log.d(TAG, "setFolderPath: 文件夹不存在去创建");
        } else {
            Log.d(TAG, "setFolderPath: 文件夹已创建");
        }
    }

    public String getFolderPath() {
        return mFolderPath;
    }

    private void closePreviewSession() {
        if (mPreviewSession != null) {
            mPreviewSession.close();
            mPreviewSession = null;
        }
    }

    private void stopRecordingVideo() {
        if (mMediaRecorder != null) {
            try {
                Log.d(TAG, "stopRecordingVideo:未调用 ");
                mMediaRecorder.stop();

            } catch (IllegalStateException e) {
                mMediaRecorder.reset();
            }

            mNextVideoAbsolutePath = null;
            startPreview();
            Log.d(TAG, "slf:停止按钮可用 ");
            findViewById(R.id.btn_video_recode).setEnabled(true);
        }


    }

    public void reopenCamera() {
        if (textureView.isAvailable()) {
            openCamera();
        } else {
            textureView.setSurfaceTextureListener(textureListener);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        startBackgroundThread();
        if (textureView.isAvailable()) {
            openCamera();
        } else {
            textureView.setSurfaceTextureListener(textureListener);
        }
    }

    private void startBackgroundThread() {
        mBackgroundThread = new HandlerThread("CameraBackground");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
    }

    @Override
    protected void onPause() {
        closeCamera();
        stopBackgroundThread();
        super.onPause();
    }

    private void stopBackgroundThread() {
        mBackgroundThread.quitSafely();
        try {
            mBackgroundThread.join();
            mBackgroundThread = null;
            mBackgroundHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private void closeCamera() {

        //mCameraOpenCloseLock.acquire();
        if (mCameraCaptureSession != null) {
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
        }
        if (mCameraDevice != null) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }
        Log.d(TAG, "closeCamera: " + "关闭相机");
         /*catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while trying to lock camera closing.",e);
        }finally {
            mCameraOpenCloseLock.release();
        }*/


    }


    private void capture() {
        try {

            //首先我们创建请求拍照的CaptureRequest
            final CaptureRequest.Builder mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            //获取屏幕方向
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            mCaptureBuilder.addTarget(mPreviewSurface);
            mCaptureBuilder.addTarget(mImageReader.getSurface());

            //设置拍照方向
            mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATION.get(rotation));


            //让相机中缩放效果和图片保持一致


            //停止预览
            mCameraCaptureSession.stopRepeating();


            //开始拍照，然后回调上面的接口重启预览，因为mCaptureBuilder设置ImageReader作为target，所以会自动回调ImageReader的onImageAvailable()方法保存图片
            CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {

                //当一个图像捕捉已经完全完成并且所有的结果元数据都可用时，这个方法就会被调用。
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    repeatPreview();
                }
            };

            mCameraCaptureSession.capture(mCaptureBuilder.build(), captureCallback, null);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    public void openCamera() {
        //获取摄像头的管理者CameraManager
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        //检查权限
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            //打开相机，第一个参数表示打开哪个摄像头，第二个参数为相机的状态回调接口，第三个参数来确定Callback在哪个线程执行，为空的话就在当前执行
            /*if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)){
                Log.d(TAG, "openCamera: "+"打开相机");
                throw new RuntimeException("Time out waiting to lock camera opening.");
            }*/
            manager.openCamera(mCameraId, stateCallback, null);
            findViewById(R.id.switch_picture).setEnabled(true);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }/*catch (InterruptedException e){
            throw new RuntimeException("Interrupted while trying to lock camera opening.",e);
        }
*/
    }

    private static class ImageSaver implements Runnable {


        private Image mImage;
        private String mFolderPath = "/abc/";

        private void setFolderPath(String path) {
            this.mFolderPath = path;
            File mFolder = new File(path);
            if (!mFolder.exists()) {
                mFolder.mkdirs();
                Log.d(TAG, "setFolderPath: 文件夹不存在去创建");
            } else {
                Log.d(TAG, "setFolderPath: 文件夹已创建");
            }
        }

        private String getFolderPath() {
            return mFolderPath;
        }

        public ImageSaver(Image image) {
            mImage = image;
        }

        private String getNowDate() {
            /*SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return simpleDateFormat.format(new Date());*/
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
            return simpleDateFormat.format(new Date());

        }

        @Override
        public void run() {
            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            setFolderPath(Environment.getExternalStorageDirectory() + getFolderPath());
            Log.d(TAG, "run: " + getFolderPath());
            File imageFile = new File(getFolderPath() + getNowDate() + new Random().nextInt(1024) + ".jpg");
            Log.d(TAG, "run: " + imageFile);
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(imageFile);
                fos.write(data, 0, data.length);
                buffer.clear();
                mImage.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                imageFile = null;
                if (fos != null) {
                    try {

                        fos.close();
                        fos = null;

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }


    private void initPermission() {
        mPermissionList.clear();//清空已经允许的没有通过的权限
        //逐个判断是否有没有通过的权限
        for (int i = 0; i < REQUESTED_PERMISSION.length; i++) {
            if (ContextCompat.checkSelfPermission(this, REQUESTED_PERMISSION[i]) != PackageManager.PERMISSION_GRANTED) {
                mPermissionList.add(REQUESTED_PERMISSION[i]);//添加还未授予的权限到mPermissionList中
            }
        }
        if (mPermissionList.size() > 0) {
            ActivityCompat.requestPermissions(this, REQUESTED_PERMISSION, PERMISSION_REQ_ID);
        } else {
            init();
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean hasPermissionDismiss = false;//有权限没有通过
        Log.d(TAG, "onRequestPermissionsResult: " + grantResults[0] + " " + requestCode);
        if (PERMISSION_REQ_ID == requestCode) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] == -1) {
                    hasPermissionDismiss = true;
                    break;
                }
            }
        }
        if (hasPermissionDismiss) {//如果有没有呗允许的权限
            showPermissionDialog();
        } else {
            //权限已经都通过了，可以将程序继续打开
            init();
        }
    }

    AlertDialog mPermissionDialog;
    String mPackName = "com.thundersoft.camera20";

    private void showPermissionDialog() {
        if (mPermissionDialog == null) {
            mPermissionDialog = new AlertDialog.Builder(this).setMessage("已禁用权限，请手动授予")
                    .setPositiveButton("设置", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            cancelPermissionDialog();
                            Uri packageURI = Uri.parse("package:" + mPackName);
                            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                            startActivity(intent);
                        }
                    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            cancelPermissionDialog();
                            MainActivity.this.finish();
                        }
                    }).create();
        }
        mPermissionDialog.show();
    }

    private void cancelPermissionDialog() {
        mPermissionDialog.cancel();
    }


}
